<!--
    @description 基于wangeditor封装的富文本编辑器组件 https://github.com/wangeditor-team/wangeditor
-->

<template>
    <div class="rich-editor">
        <div ref="toolbar" class="rich-editor-toolbar">
        </div>
        <div ref="editor" class="rich-editor-text">
        </div>
    </div>
</template>

<script>
import E from 'wangeditor/dist/wangEditor'
import {uploadImage, uploadVideo} from '@/api'

export default {
    name: 'RichEditor',
    data() {
        return {
            editor: null,
            info_: null,
            config: {}
        }
    },
    model: {
        prop: 'value',
        event: 'change2'
    },
    props: {
        value: {
            type: String,
            default: ''
        },
        isClear: {
            type: Boolean,
            default: false
        },
        // 菜单列表
        menus: {
            type: Array,
            default: () => [
                'head', // 标题
                'bold', // 粗体
                'fontSize', // 字号
                'fontName', // 字体
                'italic', // 斜体
                'underline', // 下划线
                'strikeThrough', // 删除线
                'foreColor', // 文字颜色
                'backColor', // 背景颜色
                'link', // 插入链接
                'list', // 列表
                'justify', // 对齐方式
                'quote', // 引用
                'image', // 插入图片
                'table', // 表格
                'code', // 插入代码
                'splitLine', // 分割线
                'undo', // 撤销
                'redo' // 重复
            ]
        }
    },
    watch: {
        isClear(val) {
            // 触发清除文本域内容
            if (val) {
                this.editor.txt.clear()
                this.info_ = null
            }
        },
        value: function (value) {
            console.log('value', value, this.editor.txt.html())
            
            if (value !== this.editor.txt.html()) {
                this.editor.txt.html(this.value || '')
            }
        }
        // value为编辑框输入的内容，这里我监听了一下值，当父组件调用得时候，如果给value赋值了，子组件将会显示父组件赋给的值
    },
    mounted() {
        this.config = {
            // uploadImgShowBase64: false, // base 64 存储图片
            uploadImgServer: '', // 配置图片服务器端地址
            // // uploadImgHeaders: {}, // 自定义 header
            // // uploadFileName: 'file', // 后端接受上传文件的参数名
            // uploadImgMaxSize: 5 * 1024 * 1024, // 将图片大小限制为 2M
            // uploadImgMaxLength: 1, // 限制一次最多上传 3 张图片
            // uploadImgTimeout: 3 * 60 * 1000, // 设置超时时间
            // // uploadVideoServer: '/file/video', // 配置视频服务器端地址
            // uploadVideoMaxSize: 200 * 1024 * 1024, // 100m
            // uploadVideoAccept: ['mp4']
            // // uploadVideoName: 'file'
            
            uploadImgShowBase64: false, // base 64 存储图片
            uploadImgMaxSize: 5 * 1024 * 1024, // 将图片大小限制为 2M
            uploadImgMaxLength: 1, // 限制一次最多上传 1 张图片
            uploadImgTimeout: 3 * 60 * 1000, // 设置超时时间
            // uploadVideoServer: '/file/video', // 配置视频服务器端地址
            // uploadVideoName: 'uploadFile',
            uploadVideoMaxSize: 300 * 1024 * 1024, // 100m
            uploadVideoAccept: ['mp4']
        }
        this.setEditor()
        this.editor.txt.html(this.value)
    },
    methods: {
        setEditor() {
            this.editor = new E(this.$refs.toolbar, this.$refs.editor)
            // 配置属性
            for (const key in this.config) {
                this.editor.config[key] = this.config[key]
            }
            // 配置菜单
            // this.editor.config.menus = this.menus
            
            // 自定义上传图片
            this.editor.config.customUploadImg = (resultFiles, insertImgFn) => {
                /**
                 *   resultFiles 是 input 中选中的文件列表
                 *   insertImgFn 是获取图片 url 后，插入到编辑器的方法
                 *   insertImgFn 上传图片，返回结果，将图片插入到编辑器中
                 */
                this.uploadImage(resultFiles, insertImgFn)
            }
            // 自定义上传视频
            this.editor.config.customUploadVideo = (resultFiles, insertVideoFn) => {
                this.uploadVideo(resultFiles, insertVideoFn)
            }
            
            this.editor.config.onchange = (html) => {
                console.log('改变了');
                this.info_ = html // 绑定当前组件的值
                this.$emit('change')
                this.$emit('change2', this.info_) // 将内容同步到父组件中
                
            }
            // 创建富文本编辑器
            this.editor.create()
        },
        uploadImage(files, insertImgFn) {
            console.log('files', files)
            if (files[0].size > 5 * 1024 * 1024) {
                this.$message.error('上传图片大小不能超过5M');
                return
            }
            const formData = new FormData()
            formData.append('file', files[0])
            uploadImage(formData).then(res => {
                insertImgFn(res.imgUrl)
            })
        },
        uploadVideo(files, insertVideoFn) {
            console.log('files', files)
            if (files[0].size > 300 * 1024 * 1024) {
                this.$message.error('上传视频大小不能超过300M');
                return
            }
            const formData = new FormData()
            formData.append('file', files[0])
            uploadVideo(formData).then(res => {
                insertVideoFn(res.imgUrl)
            })
        }
    },
    beforeDestroy() {
        // 销毁编辑器
        this.editor.destroy()
        this.editor = null
    }
}
</script>

<style lang="less">
.rich-editor {
    margin: 0 auto;
    position: relative;
    z-index: 0;
    border: 1px solid #c9d8db;
    line-height: initial;
    
    .rich-editor-text {
        height: 400px;
    }
    
    .w-e-toolbar {
        border-bottom: 1px solid #c9d8db;
    }
}
</style>
